/**
wopm.h (Watched Object Pool Module)

wop_type_entry are basic data structure to stored watched variables.
we wrap and pack the _table entries into a module called WOPM,
and how they interact with other sub-module.


賴念煒 - 06/12/13 新增檔案。
06/12/13 
比規格書新增updateAll()、search(string s)、remove(Entry)
、remove(stringname)，略為函式更動名稱以JAVA方式命名

	06/12/17
由於規格關係，無法實作remove (因為使用者根本不知道index為何，而我們也沒有key的概念，規格書上也沒明定variable name是unique)
search其實也是類似的情形。--(12/19解決)

	06/12/17
根據規格書推敲，我們把variable name當成key (那為何不使用map?)但規格書似乎未提及name衝突的情形？--(12/19解決)
	06/12/18
17號遇到debug半天無法找出原因的run-time error，經過多次偵錯，應該是在return en那段，原因仍然不明。
--我可以罵髒話嗎？12/19號，原封不動，過了。還我48小時！原因可能是因為vector template操作不當--(12/20 改用Vector.h)


WOP_Entry* search(stringkey);

為了解決12/17 remove的問題，我開始考慮用map來製作_table。
但是根據老師給的_table，name是可能會重複的，所以不能用map。

那麼key應該使用？ 而remove會造成嚴重的index缺洞問題，這點仍未獲得解決。
不過根據規格書，雖然有method，但是卻被強調沒有remove。
另外，根據查到的資料，remove不會幫你清除實體，仍然要手動。
另外當要add應該先確認是否已經存在。

	12/19
關於search的部份，我採用雙key---search(stringkey,WOP_Entry *parent);
因為同一parent下，其child的name為唯一。

但是parent的比較仍須確認正確度。--(12/19 採用比較parent位址)

猛然驚覺沒做成singleton，但是應該怎麼做？(--12/20完成singleton)

很糟糕的情形，關於vector template的access透過iterator總是會很糟糕...(--12/20改用smith.util.Vector.h)

	12/20
為了踢掉萬惡的template，加入一個Vector物件，Vector單位測試完成。

Vector內部元素清空要釋放記憶體，請在destructor確認--不過WOPM的存活期跟程式一樣長，應該OK

增加一個createEntry();這是為了可以很輕易的經由簡單的步驟增加Entry，而不用再每次都寫switch(type)

完成將本CLASS做成singleton

12/21
製作 findReference(string ref_addr)，以方便根據Address找尋符合的Ref。
但是函式中並未判別是否Ref_Entry，所以要提防String_Entry內容剛好符合的情形

發現很可怕的問題。這種要求實際路徑的作法，可能造成無窮回圈
例如 
p.a.b = b;
p.b.a = a;

Entry:
p.a          Ref A@12345
p.b          Ref B@FF123
A@12345    Obj b
B@FF123    Obj a
(B@FF123)a Ref A@12345
(A@12345)b Ref B@FF123

假定當我們試圖更新(B@FF123)a Ref
他ask，誰指到我的Parent B@FF123 Obj？
要是運氣不好，他會回傳給你(A@12345)b 
當再ask誰指到我的Parent A@12345 Obj？
他又給你(B@FF123)a

於是最後變成 ....b.a.b.a.b.a

這問題目前無法解決。只能祈禱不要有circle
相關的部份:
WOP_Obj_Entry::getActualPath();
WOPM::findReference();

12/22
為了解決12/21所遇到的問題，我決定放棄12/21所提到的方法，改用上->下法
也就是說，我不再讓每個Entry以不定的順序去自行處理更新，而是由WOPM「由上到下」去輪詢更新物件。
這樣每個Entry在進行更新的時候，都可以確定自己的上層已經被更新過了(因為上層自己更新過之後，才會去要求自己的child更新)
所以會刪除WOPM::findReference();

發現unfold(string s)有使用上的bug (parent string 不是一層一層取得)
這點和update可以一層一層做不同。
不得已，我必須去設置一個變數，紀錄_path

12/23
_path僅位於Obj_Entry//Array_Entry，當有任何Ref_Entry//Arrar_Ref去初始化、或是更新該Entry時，path會被記錄下來。
接下來就很輕鬆了。因為任何一個Entry必定是
1.有個arent(Obj_Entry) - 所以他的路徑必定為path+"."+name，或是path[i];
2.沒有parent，也可以稱他是top(手動觀看)，路徑為name;

所以只要確認_path被使用前有被確實更新即可。

removeEntry，和destructor，在delete物件時對於Obj_Entry的記憶體釋放處理並不好。--12/24已處理

12/23
更新method說明。


12/24
addEntry()
	//add前總要有點過濾條件...暫定為不允許任何物件有重複的key+parent，
	已經有的不會再被新增。然而，可能遭遇memory leaking
	//不過，我更贊同取代掉舊的資料。因為user手動要求觀看的資料，型態隨時會變的。

**/
#ifndef _WOPM_H_
#define	_WOPM_H_
/*------------------------------------------------------------*/
#include "all_entries.h"
#include <fstream>
#include <iostream>
#include <iomanip>
#include <vector> // include by Ming Chieh Chiou for convert the self define vector.h to the c++ vector
//這個include Vector是經由VC ++給予的"新增include目錄"功能，把前方的路徑省略
//所以如果換其他的IDE發現路徑錯誤，請自行更改路徑。
//Vector元件原位址:"smith/util/Vector.h

using namespace std;
class WOPM{
private:
	
	static WOPM* _wop;
	std::vector<WOP_Entry*> table; // 放置所有entry的vector
	WOPM();
	void updateDescents(WOP_Entry *refen) ; 
public:
	
	~WOPM();
	static WOPM* getInstance();

	/**讓使用者可以經由字串輕鬆建立一個Entry。同createEntry(name,type,NULL); */
	WOP_Entry* createEntry(string name,string type,string vartype, string addr);
	
	/**讓使用者可以輕鬆建立一個Entry，若建立失敗，則回傳NULL。僅僅只是做出一個Entry，不會自動加入表格中 */
	WOP_Entry* createEntry(string name,string type,WOP_Entry *parent, WOP_Entry *from,  bool top, string vartype, string addr);

	/** This method is called when a sleep wop is revived. What is revive? Image a wop is no longer pointed by any reference/pointers
	        it contains an old path that is used to query Minerva. Now a new pointer has value pointed to this object.
	*/
	void revive_sleepwop(WOP_Entry *en, string name, WOP_Entry* from);

	/** allow other to add a _table entry to the module
	 add前總要有點過濾條件...暫定為不允許任何物件有重複的key+parent
	 but，那些被淘汰的物件可能面臨memory leaking的問題。所以我直接在這給他們了斷... */
	void addEntry(WOP_Entry *entry) ;     
	

	/** 移除該Entry，同時釋放記憶體。 */
	void removeEntry(WOP_Entry *entry); 

   vector<WOP_Entry*> queryWOPsbyInscope(bool inscope);
	/**同search(key,NULL);供尋找top 為 true	的Entry，或是Obj_Entry之用。 */
	WOP_Entry* search(string key); 
	
    /**根據給予的條件(name+parent)取得WOP中的entry，若條件不合，則回傳NULL */
	WOP_Entry* search(string key,WOP_Entry *parent);
	

	void unfold(WOP_Entry *entry); 
	// unfolding the entry
	void updateAll();
	//update all entries in table

	/// add at 2007/06/26 - according doc v0.51 --給ref entry判斷有沒有指到現存的entry
	WOP_Entry* check_existing_objects(std::string );

	// search the wop entries with a name and a type string.
	// A name may appear more than once (e.g., pointer, pointed object,...)
	// so, a type string is needed to narrow to one answer
	// return NULL if no entry is found
	WOP_Entry * searchEntrybyName(string name, string type);

	void showAll(string title);
};
/*------------------------------------------------------------*/
#endif	//#ifndef _WOPM_H_
